﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;

namespace LostLib.Programs
{
	[Serializable]
	public class Vendor
	{
		public Vendor(string name, Uri uri, string[] publicKeys)
		{
			_name = name;
			_uri = uri;
			_tokens = new string[publicKeys.Length];
			publicKeys.CopyTo(_tokens, 0);
		}

		public string Name
		{
			get { return _name; }
			set { _name = value; }
		} string _name;
		public Uri Uri
		{
			get { return _uri; }
			set { _uri = value; }
		} Uri _uri;
		public ICollection<string> PublicKeyTokens
		{
			get { return _tokens; }
			set { throw new NotImplementedException(); }
		} string[] _tokens;

		public override string ToString()
		{
			return Name;
		}

		#region static procedures
		static Vendor[] _vendors = null;
		static Dictionary<string, Vendor> _tokenVendors;
		static string _vendorsFile = "vendors.xml";
#warning need ability to configure Vendors Files
		static FileSystemWatcher _vendorsFileWatcher;

		public static EventHandler VendorListChanged;

		static Vendor()
		{
			FileInfo info = new FileInfo(_vendorsFile);
			_vendorsFileWatcher = new FileSystemWatcher(info.DirectoryName
				, info.Name
				);
			_vendorsFileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
			_vendorsFileWatcher.Changed += new FileSystemEventHandler(_vendorsFileWatcher_Changed);
			_vendorsFileWatcher.Created += new FileSystemEventHandler(_vendorsFileWatcher_Changed);
			_vendorsFileWatcher.Renamed += new RenamedEventHandler(_vendorsFileWatcher_Renamed);
			_vendorsFileWatcher.EnableRaisingEvents = true;

			Reload();
		}

		static void _vendorsFileWatcher_Renamed(object sender, RenamedEventArgs e)
		{
			Reload();
		}

		private static void Reload()
		{
#warning надо переписать с использованием XmlSerializer
#warning нужны оповещения об изменении файла
			var doc = new XmlDocument();

			doc.Load(_vendorsFile);

			var vendors = new List<Vendor>();
			var tokenVendors = new Dictionary<string, Vendor>();
			foreach (XmlNode node in doc.SelectNodes("/vendors/vendor"))
			{
				var name = node.Attributes["name"].Value;
				var uri = new Uri(node.Attributes["uri"].Value);
				var tokens = new List<string>();
				foreach (XmlNode token in node.SelectNodes("publicKeyToken"))
					tokens.Add(token.InnerText.ToUpper());

				var vendor = new Vendor(name, uri, tokens.ToArray());
				foreach (var token in vendor._tokens)
					tokenVendors.Add(token, vendor);
				vendors.Add(vendor);
			}

			_vendors = vendors.ToArray();
			_tokenVendors = tokenVendors;

			if (VendorListChanged != null)
				VendorListChanged(typeof(Vendor), new EventArgs());
		}

		static void _vendorsFileWatcher_Changed(object sender, FileSystemEventArgs e)
		{
			Reload();
		}
		

		public static Vendor[] GetVendors()
		{
			Reload();
#warning vendors file needs to be edited by machine.config
			return _vendors.Clone() as Vendor[];
		}
		public static Vendor GetVendorByToken(string publicKeyToken)
		{
			Reload();

			Vendor result;
			if (_tokenVendors.TryGetValue(publicKeyToken, out result))
				return result;
			return null;
		}
		#endregion
	}
}
